VNC pasword authentication support for the paravirt framebuffer server.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 15 Dec 2006 17:33:31 +0000 (17:33 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 15 Dec 2006 17:33:31 +0000 (17:33 +0000)
The rules for configuring the password are equivalent of those used
for HVM, but the actual guest config option is a little different as a
result of the recent refactoring of the PVFB config file syntax.

 - If the 'vfb' option in the guest config has a 'vncpasswd' parameter
   specified
      - If the passwd is not zero length, use that
      - Else run with no authentication (important as it enables
        override of next rule)
 - Else-if the xend-config.sxp has a password specified use that
 - Else run with no authentication

Example configuration:

 - To set an explicit guest password:
    vfb = [ "type=vnc,vncunused=1,vnclisten=0.0.0.0,vncpasswd=123456"]

 - To disable authentication, overriding any XenD configured
   default password
    vfb = [ "type=vnc,vncunused=1,vnclisten=0.0.0.0,vncpasswd="]

 - To run with default XenD configured password (if any)
    vfb = [ "type=vnc,vncunused=1,vnclisten=0.0.0.0"]

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
.hgignore
tools/python/xen/xend/server/vfbif.py
tools/python/xen/xm/create.py
tools/xenfb/vncfb.c

index b445a0d342cd0ea6c4243a1c22c459ea2055fef7..d4127b6d1f81153caafb5e6eb7c08197ced05142 100644 (file)
--- a/.hgignore
+++ b/.hgignore
 ^unmodified_drivers/linux-2.6/.*\.cmd$
 ^unmodified_drivers/linux-2.6/.*\.ko$
 ^unmodified_drivers/linux-2.6/.*\.mod\.c$
+^LibVNCServer.*
index e24c2284f6b1780631193e643195e01d2ba3b545..2161ff73313b508de6e83693d07b842481f99209 100644 (file)
@@ -1,4 +1,5 @@
 from xen.xend.server.DevController import DevController
+from xen.xend.XendLogging import log
 
 from xen.xend.XendError import VmError
 import xen.xend
@@ -41,6 +42,17 @@ class VfbifController(DevController):
                      "--title", self.vm.getName() ]
         t = config.get("type", None)
         if t == "vnc":
+            passwd = None
+            if config.has_key("vncpasswd"):
+                passwd = config["vncpasswd"]
+            else:
+                passwd = xen.xend.XendRoot.instance().get_vncpasswd_default()
+            if not(passwd is None or passwd == ""):
+                self.vm.storeVm("vncpasswd", passwd)
+                log.debug("Stored a VNC password for vfb access")
+            else:
+                log.debug("No VNC passwd configured for vfb access")
+
             # Try to start the vnc backend
             args = [xen.util.auxbin.pathTo("xen-vncfb")]
             if config.has_key("vncunused"):
index aa0c03cac39678e66dd2872027ce3a3620097e69..b603b922d63746fc41b87d57d8dbec8449fc1cd2 100644 (file)
@@ -284,7 +284,7 @@ gopts.var('usbport', val='PATH',
           use="""Add a physical USB port to a domain, as specified by the path
           to that port.  This option may be repeated to add more than one port.""")
 
-gopts.var('vfb', val="type={vnc,sdl},vncunused=1,vncdisplay=N,vnclisten=ADDR,display=DISPLAY,xauthority=XAUTHORITY",
+gopts.var('vfb', val="type={vnc,sdl},vncunused=1,vncdisplay=N,vnclisten=ADDR,display=DISPLAY,xauthority=XAUTHORITY,vncpasswd=PASSWORD",
           fn=append_value, default=[],
           use="""Make the domain a framebuffer backend.
           The backend type should be either sdl or vnc.
@@ -584,7 +584,7 @@ def configure_vfbs(config_devs, vals):
             d['type'] = 'sdl'
         for (k,v) in d.iteritems():
             if not k in [ 'vnclisten', 'vncunused', 'vncdisplay', 'display',
-                          'xauthority', 'type' ]:
+                          'xauthority', 'type', 'vncpasswd' ]:
                 err("configuration option %s unknown to vfbs" % k)
             config.append([k,v])
         if not d.has_key("display") and os.environ.has_key("DISPLAY"):
index 7bb834ee2b5acbad7c68c426f817ae4f2b7ca79b..33f55eeb0d43f042f2df82789d56cbb40acea551 100644 (file)
@@ -212,15 +212,10 @@ static void on_ptr_event(int buttonMask, int x, int y, rfbClientPtr cl)
        last_y = y;
 }
 
-static void xenstore_write_vncport(int port, int domid)
+static void xenstore_write_vncport(struct xs_handle *xsh, int port, int domid)
 {
-       char *buf = NULL, *path;
+       char *buf, *path;
        char portstr[10];
-       struct xs_handle *xsh = NULL;
-
-       xsh = xs_daemon_open();
-       if (xsh == NULL)
-               return;
 
        path = xs_get_domain_path(xsh, domid);
        if (path == NULL) {
@@ -248,6 +243,56 @@ static void xenstore_write_vncport(int port, int domid)
 }
 
 
+static int xenstore_read_vncpasswd(struct xs_handle *xsh, int domid, char *pwbuf, int pwbuflen)
+{
+       char buf[256], *path, *uuid = NULL, *passwd = NULL;
+       unsigned int len, rc = 0;
+
+       if (xsh == NULL) {
+               return -1;
+       }
+
+       path = xs_get_domain_path(xsh, domid);
+       if (path == NULL) {
+               fprintf(stderr, "xs_get_domain_path() error\n");
+               return -1;
+       }
+
+       snprintf(buf, 256, "%s/vm", path);
+       uuid = xs_read(xsh, XBT_NULL, buf, &len);
+       if (uuid == NULL) {
+               fprintf(stderr, "xs_read(): uuid get error\n");
+               free(path);
+               return -1;
+       }
+
+       snprintf(buf, 256, "%s/vncpasswd", uuid);
+       passwd = xs_read(xsh, XBT_NULL, buf, &len);
+       if (passwd == NULL) {
+               free(uuid);
+               free(path);
+               return rc;
+       }
+
+       strncpy(pwbuf, passwd, pwbuflen-1);
+       pwbuf[pwbuflen-1] = '\0';
+
+       fprintf(stderr, "Got a VNC password read from XenStore\n");
+
+       passwd[0] = '\0';
+       snprintf(buf, 256, "%s/vncpasswd", uuid);
+       if (xs_write(xsh, XBT_NULL, buf, passwd, len) == 0) {
+               fprintf(stderr, "xs_write() vncpasswd failed\n");
+               rc = -1;
+       }
+
+       free(passwd);
+       free(uuid);
+       free(path);
+
+       return rc;
+}
+
 static void vnc_update(struct xenfb *xenfb, int x, int y, int w, int h)
 {
        rfbScreenInfoPtr server = xenfb->user_data;
@@ -281,6 +326,10 @@ int main(int argc, char **argv)
        char portstr[10];
        char *endp;
        int r;
+       struct xs_handle *xsh;
+       char vncpasswd[1024];
+
+       vncpasswd[0] = '\0';
 
        while ((opt = getopt_long(argc, argv, "d:p:t:u", options,
                                  NULL)) != -1) {
@@ -353,6 +402,19 @@ int main(int argc, char **argv)
                exit(1);
        }
 
+       xsh = xs_daemon_open();
+       if (xsh == NULL) {
+               fprintf(stderr, "cannot open connection to xenstore\n");
+               exit(1);
+       }
+
+
+       if (xenstore_read_vncpasswd(xsh, domid, vncpasswd, sizeof(vncpasswd)/sizeof(char)) < 0) {
+               fprintf(stderr, "cannot read VNC password from xenstore\n");
+               exit(1);
+       }
+         
+
        server = rfbGetScreen(&fake_argc, fake_argv, 
                              xenfb->width, xenfb->height,
                              8, 3, xenfb->depth / 8);
@@ -367,6 +429,21 @@ int main(int argc, char **argv)
         if (unused)
                server->autoPort = true;
 
+       if (vncpasswd[0]) {
+               char **passwds = malloc(sizeof(char**)*2);
+               if (!passwds) {
+                       fprintf(stderr, "cannot allocate memory (%s)\n", strerror(errno));
+                       exit(1);
+               }
+               fprintf(stderr, "Registered password\n");
+               passwds[0] = vncpasswd;
+               passwds[1] = NULL;
+
+               server->authPasswdData = passwds;
+               server->passwordCheck = rfbCheckPasswordByList;
+       } else {
+               fprintf(stderr, "Running with no password\n");
+       }
        server->serverFormat.redShift = 16;
        server->serverFormat.greenShift = 8;
        server->serverFormat.blueShift = 0;
@@ -379,7 +456,7 @@ int main(int argc, char **argv)
 
        rfbRunEventLoop(server, -1, true);
 
-        xenstore_write_vncport(server->port, domid);
+        xenstore_write_vncport(xsh, server->port, domid);
 
        for (;;) {
                FD_ZERO(&readfds);